use std::ptr::null;
// src/handler/login_handler.rs
use axum::{http::StatusCode, response::Json, extract::State, Extension};
use sea_orm::{EntityTrait};
use std::sync::Arc;
use axum::http::{HeaderMap, HeaderValue};
use axum::response::IntoResponse;
use axum_extra::extract::CookieJar;
use futures_util::TryFutureExt;
use crate::app::AppState;
use crate::graphql::user_graphql::{LoginUserInput, RegisterUserInput, UserLoginObject, UserTokenObject};
use crate::handler::user_handler;
use crate::handler::user_handler::{logout, refresh_token_handler, registry_user_form};
use crate::utility::jwt::UserInfo;

// 登录处理器
pub async fn login_handle(
    State(state): State<Arc<AppState>>,
    Json(payload): Json<LoginUserInput>,
) -> Result<impl IntoResponse, (StatusCode, Json<String>)> {

    let out = user_handler::login(&state.db, &state.redis, payload).await
        .map_err(|e| {
            (
                StatusCode::UNAUTHORIZED,
                Json(e.message),
            )
        })?;

    // 创建响应头
    let mut headers = HeaderMap::new();

    // 在设置 Cookie 时添加 Domain 和 SameSite 属性
    let cookie_value = format!(
        "refresh_token={}; Domain=wujianming.xyz; Path=/api/auth/refresh_token; HttpOnly; SameSite=None; Secure; Max-Age={}",
        out.refresh_token,
        7 * 24 * 60 * 60 // 7天，单位为秒
    );

    if let Ok(cookie_header) = HeaderValue::from_str(&cookie_value) {
        headers.insert("Set-Cookie", cookie_header);
    }

    // 构造正确类型的响应：(StatusCode, HeaderMap, Json<T>) 已经实现了 IntoResponse
    let response = (StatusCode::OK, headers, Json(out)).into_response();

    Ok(response)
}


// 登出处理器
pub async fn logout_handle(
    State(state): State<Arc<AppState>>,
    user_info: Extension<UserInfo>
) -> Result<impl IntoResponse, (StatusCode, Json<String>)> {
    // 在实际应用中，你可能需要将 token 加入黑名单
    // 这里简单返回成功


    let out = logout(&state.db, &state.redis, user_info.user_id).await.map_err(|e| {
        (
            StatusCode::INTERNAL_SERVER_ERROR,
            Json(e.message),
        )
    })?;

    if out {
        // 创建响应头
        let mut headers = HeaderMap::new();

        // 设置 refresh_token cookie 过期（清除 cookie）
        let cookie_value = "refresh_token=; Path=/api/auth/refresh_token; HttpOnly; Secure; SameSite=Strict; Max-Age=0";

        if let Ok(cookie_header) = HeaderValue::from_str(&cookie_value) {
            headers.insert("Set-Cookie", cookie_header);
        }

        // 返回带有清除 cookie 头的响应
        let response = (StatusCode::OK, headers, Json(serde_json::json!({
            "message": "登出成功"
        }))).into_response();
        Ok(response)
    }else {
        Err((
            StatusCode::INTERNAL_SERVER_ERROR,
            Json("登出失败".to_string())
        ))
    }
}

pub async fn refresh_token_handle(
    State(state): State<Arc<AppState>>,
    jar: CookieJar,
) -> Result<impl IntoResponse, (StatusCode, Json<String>)> {
    // 刷新令牌的逻辑
    // 1. 验证当前的 refresh_token 是否有效
    // 2. 生成新的 access_token 和 refresh_token
    // 3. 返回新的令牌
    // 获取特定的 cookie 值
    if let Some(refresh_token_cookie) = jar.get("refresh_token") {
        let refresh_token = refresh_token_cookie.value();
        // 处理 refresh_token...
        let token = refresh_token_handler(&state.db, &state.redis, refresh_token).await.map_err(|e| {
            (
                StatusCode::UNAUTHORIZED,
                Json(e.message),
            )
        })?;
        // 返回带有清除 cookie 头的响应
        let response = (StatusCode::OK, Json(serde_json::json!(token))).into_response();
        return Ok(response);
    }

    Err((
        StatusCode::OK,
        "message: 没有找到 refresh_token cookie".to_string().into()
    ))
}

// 注册处理器
pub async fn register_handle(
    State(state): State<Arc<AppState>>,
    Json(payload): Json<RegisterUserInput>,
) -> Result<impl IntoResponse, (StatusCode, Json<String>)> {
    // 注册逻辑
    // 1. 接收注册信息
    // 2. 创建新用户
    // 3. 返回注册结果

    let user_out = registry_user_form(&state.db, &state.redis, payload).await
        .map_err(
            |e| {
                (
                    StatusCode::BAD_REQUEST,
                    Json(e.message),
                )
            }
        )?;

    // 创建响应头
    let mut headers = HeaderMap::new();

    // 设置 HTTPOnly Cookie 用于 refresh_token
    let cookie_value = format!(
        "refresh_token={}; Path=/api/auth/refresh_token; HttpOnly; Secure; SameSite=Strict; Max-Age={}",
        user_out.refresh_token,
        7 * 24 * 60 * 60 // 7天，单位为秒
    );

    if let Ok(cookie_header) = HeaderValue::from_str(&cookie_value) {
        headers.insert("Set-Cookie", cookie_header);
    }

    // 构造正确类型的响应：(StatusCode, HeaderMap, Json<T>) 已经实现了 IntoResponse
    let response = (StatusCode::OK, headers, Json(user_out)).into_response();


    Ok(response)
}